package com.wj.init.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;

/**
 * @author wujian
 * @date 2019/8/5 11:04
 * @desc http工具类
 */
@Slf4j
public class HttpUtils {

    private static RestTemplate template = new RestTemplate();

    /**
     * get请求
     *
     * @param url    请求地址
     * @param tClass 需要返回的结果类型
     * @param <T>    泛型
     * @return
     */
    public static <T> T get(String url, Map<String, Object> params, Class<T> tClass) {
        return template.getForObject(url, tClass, params == null ? new HashMap<>(0) : params);
    }

    /**
     * POST请求
     *
     * @param url    请求地址
     * @param params 参数
     * @param tClass 返回类型
     * @param <T>    泛型
     * @return
     */
    public static <T> T post(String url, Object params, Class<T> tClass) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.parseMediaType("application/json; charset=UTF-8"));
        String json = Utils.MAPPER.writeValueAsString(params);
        HttpEntity<String> formEntity = new HttpEntity<>(json, headers);
        return template.postForObject(url, formEntity, tClass);
    }


    /**
     * delete
     *
     * @param url    请求地址
     * @param params 请求参数
     * @return
     */
    public static void delete(String url, Map<String, Object> params) {
        template.delete(url, params);
    }

    /**
     * 接口下载方法
     *
     * @param path     下载文件路径
     * @param response res
     */
    public static void download(String path, HttpServletResponse response) {
        try {
            String fileName = path.split("/")[path.split("/").length - 1];
            BufferedInputStream br = new BufferedInputStream(new FileInputStream(path));
            byte[] buf = new byte[1024];
            response.reset();
            response.setContentType("application/x-msdownload");
            response.setHeader("Content-Disposition", "attachment; filename=" + new String(fileName.getBytes(Charset.forName("UTF-8")), Charset.forName("ISO-8859-1")));
            OutputStream out = response.getOutputStream();
            int len;
            while ((len = br.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            br.close();
            out.close();
        } catch (Exception e) {
            log.info("文件_" + path + "下载失败");
            e.printStackTrace();
        }
    }

    /**
     * 获取请求主机IP地址,如果通过代理进来，则透过防火墙获取真实IP地址;
     *
     * @param request 请求信息
     * @return
     * @throws IOException
     */
    public static String getIpAddress(HttpServletRequest request) {
        // 获取请求主机IP地址,如果通过代理进来，则透过防火墙获取真实IP地址
        String ip = request.getHeader("X-Forwarded-For");
        if (log.isInfoEnabled()) {
            log.info("getIpAddress(HttpServletRequest) - X-Forwarded-For - String ip=" + ip);
        }

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
                if (log.isInfoEnabled()) {
                    log.info("getIpAddress(HttpServletRequest) - Proxy-Client-IP - String ip=" + ip);
                }
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
                if (log.isInfoEnabled()) {
                    log.info("getIpAddress(HttpServletRequest) - WL-Proxy-Client-IP - String ip=" + ip);
                }
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
                if (log.isInfoEnabled()) {
                    log.info("getIpAddress(HttpServletRequest) - HTTP_CLIENT_IP - String ip=" + ip);
                }
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
                if (log.isInfoEnabled()) {
                    log.info("getIpAddress(HttpServletRequest) - HTTP_X_FORWARDED_FOR - String ip=" + ip);
                }
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
                if (log.isInfoEnabled()) {
                    log.info("getIpAddress(HttpServletRequest) - getRemoteAddr - String ip=" + ip);
                }
            }
        } else if (ip.length() > 15) {
            String[] ips = ip.split(",");
            for (int index = 0; index < ips.length; index++) {
                String strIp = ips[index];
                if (!("unknown".equalsIgnoreCase(strIp))) {
                    ip = strIp;
                    break;
                }
            }
        }
        return ip;
    }
}
